home *** CD-ROM | disk | FTP | other *** search
/ Team Palmtops 7 / Palmtops_numero07.iso / WinCE / SDKWindowsCE / HandHeldPCPro30 / sdk.exe / Jupiter SDK / data1.cab / MFC / src / winfrmx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-19  |  11.0 KB  |  428 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CORE3_SEG
  14. #pragma code_seg(AFX_CORE3_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // Basic Help support
  24.  
  25. #if defined(_WIN32_WCE)
  26. void CWnd::OnHelp()  // use context to derive help context 
  27.     // attempt to get help from whoever is tracking 
  28.     // just handle the main window case 
  29.     CWnd* pWnd = AfxGetMainWnd();
  30.     HWND hWnd = pWnd->GetSafeHwnd();
  31.     if (hWnd != NULL)
  32.     {
  33.         // attempt to process help
  34.         ::SendMessage(hWnd, WM_COMMANDHELP, 0, 0);
  35.         return;
  36.     }
  37.     // No context available, bring up default.
  38.     SendMessage(WM_COMMAND, ID_DEFAULT_HELP);
  39. }
  40. #else // _WIN32_WCE
  41. void CWnd::OnHelp()  // use context to derive help context
  42. {
  43.     // attempt to get help from whoever is tracking
  44.     HWND hWnd = ::GetCapture();
  45.     while (hWnd != NULL)
  46.     {
  47.         // attempt to process help
  48.         if (::SendMessage(hWnd, WM_COMMANDHELP, 0, 0))
  49.             return;
  50.  
  51.         // check next parent/owner in the parent/owner chain
  52.         hWnd = AfxGetParentOwner(hWnd);
  53.     }
  54.     // attempt to get help from whoever has the focus
  55.     hWnd = ::GetFocus();
  56.     while (hWnd != NULL)
  57.     {
  58.         // attempt to process help
  59.         if (::SendMessage(hWnd, WM_COMMANDHELP, 0, 0))
  60.             return;
  61.  
  62.         // check next parent/owner in the parent/owner chain
  63.         hWnd = AfxGetParentOwner(hWnd);
  64.     }
  65.     // attempt to get help from the active window
  66.     CWnd* pWnd = GetTopLevelParent();
  67.     hWnd = ::GetLastActivePopup(pWnd->GetSafeHwnd());
  68.     while (hWnd != NULL)
  69.     {
  70.         // attempt to process help
  71.         if (::SendMessage(hWnd, WM_COMMANDHELP, 0, 0))
  72.             return;
  73.  
  74.         // check next parent/owner in the parent/owner chain
  75.         hWnd = AfxGetParentOwner(hWnd);
  76.     }
  77.     // No context available, bring up default.
  78.     SendMessage(WM_COMMAND, ID_DEFAULT_HELP);
  79. }
  80. #endif // _WIN32_WCE
  81.  
  82. void CFrameWnd::OnHelp()
  83. {
  84.     // Be careful not call WinHelp when the error is failing to lauch help
  85.     if (m_dwPromptContext != 0)
  86.     {
  87.         if (m_dwPromptContext != HID_BASE_PROMPT+AFX_IDP_FAILED_TO_LAUNCH_HELP)
  88.             AfxGetApp()->WinHelp(m_dwPromptContext);
  89.         return;
  90.     }
  91.     CWnd::OnHelp();
  92. }
  93.  
  94. #if !defined(_WIN32_WCE)
  95. void CWnd::OnHelpIndex()
  96. {
  97.     AfxGetApp()->WinHelp(0L, HELP_INDEX);
  98. }
  99.  
  100. void CWnd::OnHelpFinder()
  101. {
  102.     AfxGetApp()->WinHelp(0L, HELP_FINDER);
  103. }
  104.  
  105. void CWnd::OnHelpUsing()
  106. {
  107.     AfxGetApp()->WinHelp(0L, HELP_HELPONHELP);
  108. }
  109. #endif // _WIN32_WCE
  110.  
  111. /////////////////////////////////////////////////////////////////////////////
  112. // Context Help Mode support
  113.  
  114. #if !defined(_WIN32_WCE)
  115. BOOL CFrameWnd::CanEnterHelpMode()
  116. {
  117.     ASSERT(m_bHelpMode != HELP_ACTIVE); // already in help mode?
  118.  
  119.     // unable to start help if the cursor cannot be loaded from the resources
  120.     if (afxData.hcurHelp == NULL)
  121.     {
  122.         afxData.hcurHelp = ::LoadCursor(NULL, IDC_HELP);
  123.         if (afxData.hcurHelp == NULL)
  124.         {
  125.             // load help cursor after handles have been setup
  126.             HINSTANCE hInst = AfxFindResourceHandle(
  127.                 MAKEINTRESOURCE(AFX_IDC_CONTEXTHELP), RT_GROUP_CURSOR);
  128.             afxData.hcurHelp = LoadCursor(hInst,
  129.                 MAKEINTRESOURCE(AFX_IDC_CONTEXTHELP));
  130.         }
  131.         if (afxData.hcurHelp == NULL)
  132.             return FALSE;
  133.     }
  134.  
  135.     // return TRUE if there is a handler for ID_CONTEXT_HELP
  136.     AFX_CMDHANDLERINFO info;
  137.     return OnCmdMsg(ID_CONTEXT_HELP, CN_COMMAND, NULL, &info);
  138. }
  139.  
  140. void CFrameWnd::OnContextHelp()
  141. {
  142.     // don't enter twice, and don't enter if initialization fails
  143.     if (m_bHelpMode == HELP_ACTIVE || !CanEnterHelpMode())
  144.         return;
  145.  
  146.     // don't enter help mode with pending WM_EXITHELPMODE message
  147.     MSG msg;
  148.     if (PeekMessage(&msg, m_hWnd, WM_EXITHELPMODE, WM_EXITHELPMODE,
  149.         PM_REMOVE|PM_NOYIELD))
  150.     {
  151.         return;
  152.     }
  153.  
  154.     BOOL bHelpMode = m_bHelpMode;
  155.     ASSERT(m_bHelpMode == HELP_INACTIVE || m_bHelpMode == HELP_ENTERING);
  156.     m_bHelpMode = HELP_ACTIVE;
  157.  
  158. #ifndef _AFX_NO_OLE_SUPPORT
  159.     // allow any in-place active servers to go into help mode
  160.     if (bHelpMode != HELP_ENTERING && m_pNotifyHook != NULL &&
  161.         !m_pNotifyHook->OnContextHelp(TRUE))
  162.     {
  163.         TRACE0("Error: an in-place server failed to enter context help mode.\n");
  164.         m_pNotifyHook->OnContextHelp(FALSE);    // undo partial help mode
  165.         m_bHelpMode = HELP_INACTIVE;
  166.         return;
  167.     }
  168. #endif
  169.  
  170.     if (bHelpMode == HELP_INACTIVE)
  171.     {
  172.         // need to delay help startup until later
  173.         PostMessage(WM_COMMAND, ID_CONTEXT_HELP);
  174.         m_bHelpMode = HELP_ENTERING;
  175.         return;
  176.     }
  177.  
  178.     ASSERT(m_bHelpMode == HELP_ACTIVE);
  179.  
  180.     // display special help mode message on status bar
  181.     UINT nMsgSave = (UINT)SendMessage(WM_SETMESSAGESTRING,
  182.         (WPARAM)AFX_IDS_HELPMODEMESSAGE);
  183.     if (nMsgSave == 0)
  184.         nMsgSave = AFX_IDS_IDLEMESSAGE;
  185.  
  186.     DWORD   dwContext = 0;
  187.     POINT   point;
  188.  
  189.     GetCursorPos(&point);
  190.     SetHelpCapture(point, NULL);
  191.     LONG lIdleCount = 0;
  192.     CWinApp* pApp = AfxGetApp();
  193.  
  194.     while (m_bHelpMode)
  195.     {
  196.         if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
  197.         {
  198.             if (!ProcessHelpMsg(msg, &dwContext))
  199.                 break;
  200.             ASSERT(dwContext == 0);
  201.         }
  202.         else if (!pApp->OnIdle(lIdleCount++))
  203.         {
  204.             lIdleCount = 0;
  205.             WaitMessage();
  206.         }
  207.     }
  208.  
  209.     m_bHelpMode = HELP_INACTIVE;
  210.     ReleaseCapture();
  211.  
  212.     // make sure the cursor is set appropriately
  213.     SetCapture();
  214.     ReleaseCapture();
  215.  
  216.     // restore original status bar text
  217.     SendMessage(WM_SETMESSAGESTRING, (WPARAM)nMsgSave);
  218.  
  219. #ifndef _AFX_NO_OLE_SUPPORT
  220.     // tell in-place servers to exit Shift+F1 help mode
  221.     if (m_pNotifyHook != NULL)
  222.         m_pNotifyHook->OnContextHelp(FALSE);
  223. #endif
  224.  
  225.     if (dwContext != 0)
  226.     {
  227.         if (dwContext == -1)
  228.             SendMessage(WM_COMMAND, ID_DEFAULT_HELP);
  229.         else
  230.             pApp->WinHelp(dwContext);
  231.     }
  232.     PostMessage(WM_KICKIDLE);    // trigger idle update
  233. }
  234.  
  235. /////////////////////////////////////////////////////////////////////////////
  236. // OnContextHelp helpers.
  237.  
  238. HWND CFrameWnd::SetHelpCapture(POINT point, BOOL* pbDescendant)
  239.     // set or release capture, depending on where the mouse is
  240.     // also assign the proper cursor to be displayed.
  241. {
  242.     if (!m_bHelpMode)
  243.         return NULL;
  244.  
  245.     HWND hWndCapture = ::GetCapture();
  246.     CWnd* pWndHit = WindowFromPoint(point);
  247.     HWND hWndHit = pWndHit->GetSafeHwnd();
  248.     CWnd* pTopHit = pWndHit->GetTopLevelParent();
  249.     CWnd* pTopActive = GetActiveWindow()->GetTopLevelParent();
  250.     BOOL bDescendant = FALSE;
  251.     HTASK hCurTask = (HTASK)GetCurrentThreadId();
  252.     HTASK hTaskHit = hWndHit != NULL ? ::GetWindowTask(hWndHit) : NULL;
  253.  
  254.     if (pTopActive == NULL || hWndHit == ::GetDesktopWindow())
  255.     {
  256.         if (hWndCapture == m_hWnd)
  257.             ReleaseCapture();
  258.         SetCursor(afxData.hcurArrow);
  259.     }
  260.     else if (pTopActive == NULL ||
  261.         hWndHit == NULL || hCurTask != hTaskHit ||
  262.         !AfxIsDescendant(m_hWnd, hWndHit))
  263.     {
  264.         if (hCurTask != hTaskHit)
  265.             hWndHit = NULL;
  266.         if (hWndCapture == m_hWnd)
  267.             ReleaseCapture();
  268.     }
  269.     else
  270.     {
  271.         bDescendant = TRUE;
  272.         if (pTopActive != pTopHit)
  273.             hWndHit = NULL;
  274.         else
  275.         {
  276.             if (hWndCapture != m_hWnd)
  277.                 ::SetCapture(m_hWnd);
  278.             SetCursor(afxData.hcurHelp);
  279.         }
  280.     }
  281.     if (pbDescendant != NULL)
  282.         *pbDescendant = bDescendant;
  283.     return hWndHit;
  284. }
  285.  
  286. AFX_STATIC DWORD AFXAPI _AfxMapClientArea(HWND hWnd, POINT point)
  287. {
  288.     DWORD dwContext;
  289.  
  290.     do
  291.     {
  292.         ASSERT(::IsWindow(hWnd));
  293.  
  294.         // check current window
  295.         ::ScreenToClient(hWnd, &point);
  296.         dwContext = ::SendMessage(hWnd, WM_HELPHITTEST, 0,
  297.             MAKELONG(point.x, point.y));
  298.         ::ClientToScreen(hWnd, &point);
  299.  
  300.         // don't use owner's of popup windows, just child/parent relationship
  301.         if ((GetWindowLong(hWnd, GWL_STYLE) & WS_CHILD) == 0)
  302.             break;
  303.         // check parent window
  304.         hWnd = ::GetParent(hWnd);
  305.     }
  306.     while (hWnd && dwContext == 0);
  307.  
  308.     return dwContext == 0 ? -1 : dwContext;
  309. }
  310.  
  311. AFX_STATIC DWORD AFXAPI _AfxMapNonClientArea(int iHit)
  312. {
  313.     ASSERT(iHit != HTCLIENT);
  314.  
  315.     if (iHit < 0 || iHit > HTHELP)
  316.         return (DWORD)-1;
  317.  
  318.     return HID_BASE_NCAREAS+iHit;
  319. }
  320.  
  321. BOOL CFrameWnd::ProcessHelpMsg(MSG& msg, DWORD* pContext)
  322. {
  323.     ASSERT(pContext != NULL);
  324.  
  325.     if (msg.message == WM_EXITHELPMODE ||
  326.         (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE))
  327.     {
  328.         PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
  329.         return FALSE;
  330.     }
  331.  
  332.     CPoint point;
  333.     if ((msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) ||
  334.         (msg.message >= WM_NCMOUSEFIRST && msg.message <= WM_NCMOUSELAST))
  335.     {
  336.         BOOL bDescendant;
  337.         HWND hWndHit = SetHelpCapture(msg.pt, &bDescendant);
  338.         if (hWndHit == NULL)
  339.             return TRUE;
  340.  
  341.         if (bDescendant)
  342.         {
  343.             if (msg.message != WM_LBUTTONDOWN)
  344.             {
  345.                 // Hit one of our owned windows -- eat the message.
  346.                 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
  347.                 return TRUE;
  348.             }
  349.             int iHit = (int)::SendMessage(hWndHit, WM_NCHITTEST, 0,
  350.                 MAKELONG(msg.pt.x, msg.pt.y));
  351.             if (iHit == HTMENU || iHit == HTSYSMENU)
  352.             {
  353.                 ASSERT(::GetCapture() == m_hWnd);
  354.                 ReleaseCapture();
  355.                 // the message we peeked changes into a non-client because
  356.                 // of the release capture.
  357.                 GetMessage(&msg, NULL, WM_NCLBUTTONDOWN, WM_NCLBUTTONDOWN);
  358.                 DispatchMessage(&msg);
  359.                 GetCursorPos(&point);
  360.                 SetHelpCapture(point, NULL);
  361.             }
  362.             else if (iHit == HTCLIENT)
  363.             {
  364.                 *pContext = _AfxMapClientArea(hWndHit, msg.pt);
  365.                 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
  366.                 return FALSE;
  367.             }
  368.             else
  369.             {
  370.                 *pContext = _AfxMapNonClientArea(iHit);
  371.                 PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
  372.                 return FALSE;
  373.             }
  374.         }
  375.         else
  376.         {
  377.             // Hit one of our apps windows (or desktop) -- dispatch the message.
  378.             PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
  379.  
  380.             // Dispatch mouse messages that hit the desktop!
  381.             DispatchMessage(&msg);
  382.         }
  383.     }
  384.     else if (msg.message == WM_SYSCOMMAND ||
  385.              (msg.message >= WM_KEYFIRST && msg.message <= WM_KEYLAST))
  386.     {
  387.         if (::GetCapture() != NULL)
  388.         {
  389.             ReleaseCapture();
  390.             MSG msg;
  391.             while (PeekMessage(&msg, NULL, WM_MOUSEFIRST,
  392.                 WM_MOUSELAST, PM_REMOVE|PM_NOYIELD));
  393.         }
  394.         if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_NOREMOVE))
  395.         {
  396.             GetMessage(&msg, NULL, msg.message, msg.message);
  397.             if (!PreTranslateMessage(&msg))
  398.             {
  399.                 TranslateMessage(&msg);
  400.                 if (msg.message == WM_SYSCOMMAND ||
  401.                   (msg.message >= WM_SYSKEYFIRST &&
  402.                     msg.message <= WM_SYSKEYLAST))
  403.                 {
  404.                     // only dispatch system keys and system commands
  405.                     ASSERT(msg.message == WM_SYSCOMMAND ||
  406.                          (msg.message >= WM_SYSKEYFIRST &&
  407.                           msg.message <= WM_SYSKEYLAST));
  408.                     DispatchMessage(&msg);
  409.                 }
  410.             }
  411.         }
  412.         GetCursorPos(&point);
  413.         SetHelpCapture(point, NULL);
  414.     }
  415.     else
  416.     {
  417.         // allow all other messages to go through (capture still set)
  418.         if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE))
  419.             DispatchMessage(&msg);
  420.     }
  421.  
  422.     return TRUE;
  423. }
  424. #endif // _WIN32_WCE
  425.  
  426. /////////////////////////////////////////////////////////////////////////////
  427.